package com.bwie.service.impl;

import cn.hutool.core.util.RandomUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.bwie.poi.StringUtils;
import com.bwie.pojo.TbUser;
import com.bwie.service.TbUserService;
import com.bwie.mapper.TbUserMapper;
import com.bwie.utils.MD5Utils;
import com.bwie.utils.MobileMessageUtil;
import com.bwie.utils.R;
import com.bwie.vo.LoginUserVo;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;
import io.netty.util.internal.UnstableApi;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.concurrent.TimeUnit;

/**
* @author 叶雨洁
* @description 针对表【tb_user】的数据库操作Service实现
* @createDate 2025-07-15 09:23:29
*/
@Service
public class TbUserServiceImpl extends ServiceImpl<TbUserMapper, TbUser>
    implements TbUserService{

    @Autowired
    TbUserMapper userMapper;

    @Autowired
    StringRedisTemplate redisTemplate;
    @Override
    @Transactional(rollbackFor = Exception.class)
    public R userLogin(LoginUserVo loginUserVo) {

        //登录框只有一个，用户登录既可以使用邮箱登录，也可以使用手机号登录（2分）
        TbUser user = userMapper.selectOne(
                new QueryWrapper<TbUser>().lambda().eq(TbUser::getPhone, loginUserVo.getPhone()).or(new QueryWrapper<TbUser>().lambda().equals(TbUser::getEmail,loginUserVo.getEmail()))
        );
        if(user==null){
            return R.ERROR(500,"用户还没注册请先注册");
        }

        if(!user.getPassword().equals(loginUserVo.getPassword())){
            return R.ERROR(500,"密码错误请重新输入");
        }
        //JWT实现系统鉴权。（2分）
        String token = Jwts.builder().signWith(SignatureAlgorithm.HS256, "bwie").claim("userId", user.getUserId())
                .claim("phone", user.getPhone()).claim("password", user.getPassword()).compact();
        String key="token-"+user.getUserId();
        //会话管理与Redis集成。会话为30分钟的有效期。（2分）
        redisTemplate.opsForValue().set(key,token,30, TimeUnit.MINUTES);

        user.setToken(token);
        return R.OK(user);
    }

    @Override
    public R regixUser(TbUser tbUser) {

        TbUser tbUser1 = userMapper.selectOne(
                new QueryWrapper<TbUser>().lambda().eq(TbUser::getPhone, tbUser.getPhone())
        );
        //在用户注册过程中，必须对输入的手机号进行唯一性检查，一个手机号只能注册一个用户。（2分）
        if(tbUser1!=null){
            return R.ERROR(500,"该用户已存在不能注册");
        }
        String key2="phone-"+tbUser.getPhone();
        String redisCode = redisTemplate.opsForValue().get(key2);
        if(!StringUtils.isNotEmpty(redisCode)){
            return R.ERROR(500,"验证码已过期");
        }
        if(!redisCode.equals(tbUser.getPhoneCode())){
            return R.ERROR(500,"验证码错误");
        }

        String password = tbUser.getPassword();
        String encrypt = MD5Utils.encrypt(password);
        tbUser.setPassword(encrypt);

        userMapper.insert(tbUser);
        return R.OK();
    }

    @Override
    public R sendCode(LoginUserVo loginUserVo) {
        //发送验证码需要限制60内只能发送一次（2分）
        String key2="phone-"+loginUserVo.getPhone();
        if(redisTemplate.hasKey(key2)){
            return R.ERROR(500,"60内只能发送一次");
        }

        String phoneCode = RandomUtil.randomNumbers(4);
        //注册需要使用手机验证码发送并验证。（2分）
        MobileMessageUtil.sendMobileMessage(loginUserVo.getPhone(),phoneCode);
        System.out.println("验证码是"+phoneCode);


        //验证码信息存储至Redis。设置为5分钟的有效期。（2分）
        redisTemplate.opsForValue().set(loginUserVo.getPhone(),phoneCode,5,TimeUnit.MINUTES);
        redisTemplate.opsForValue().set(key2,phoneCode,1,TimeUnit.MINUTES);


        return R.OK();
    }

    @Override
    public R updatePwd(LoginUserVo loginUserVo) {

        TbUser tbUser1 = userMapper.selectOne(
                new QueryWrapper<TbUser>().lambda().eq(TbUser::getPhone, loginUserVo.getPhone())
        );
        //在用户注册过程中，必须对输入的手机号进行唯一性检查，一个手机号只能注册一个用户。（2分）
        if(tbUser1==null){
            return R.ERROR(500,"该用户不存在");
        }
        String key2="phone-"+ loginUserVo.getPhone();
        String redisCode = redisTemplate.opsForValue().get(key2);
        if(!StringUtils.isNotEmpty(redisCode)){
            return R.ERROR(500,"验证码已过期");
        }
        //进行验证码校验真伪，若输入错误3次，则需要让本次发送的验证码失效。（3分）
        Integer num = tbUser1.getNum();
        if(!redisCode.equals(loginUserVo.getPhoneCode())){
            num++;
            System.out.println("验证码错误次数加1");
            if(num==3){
                redisTemplate.delete(key2);
                tbUser1.setNum(1);
            }
            return R.ERROR(500,"验证码错误");
        }

        System.out.println(loginUserVo.getPassword());
        tbUser1.setPassword(loginUserVo.getPassword());

        userMapper.updateById(loginUserVo);
        return R.OK();
    }
}




